package com.qfmy.webapp.aop;

import com.qfmy.model.annotation.LoginLog;
import com.qfmy.model.query.user.UserQuery;
import com.qfmy.webapp.mapper.common.LoginLogMapper;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.lang.reflect.Parameter;

/**
 * @author 清风明月
 * @Package com.qfmy.web.app.aop
 * @date 2025/11/26
 * @description 登入的切面类
 */
@Slf4j
@Aspect
@Component
@SuppressWarnings("all")
public class LoginAspect {

    /**
     * 定义切点表达式
     */
    @Pointcut("@annotation(com.qfmy.model.annotation.LoginLog)")
    public void loginPointCut() {}

    /**
     * 注入日志mapper
     */
    @Autowired
    private LoginLogMapper loginLogMapper;

    /**
     * 创建登入的切面逻辑
     */
    @Around("loginPointCut()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        // 获取方法的注解
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        // 获取方法的参数
        Method method = signature.getMethod();
        //获取方法的注解
        LoginLog loginLog = method.getAnnotation(LoginLog.class);
        //获取操作名
        String operation = loginLog.operation();
        //记录开始时间
        long startTime = System.currentTimeMillis();
        //创建日志对象
        com.qfmy.model.entity.common.LoginLog lg = new com.qfmy.model.entity.common.LoginLog();
        try {
            //获取方法上的参数
            Object[] args = joinPoint.getArgs();
            // 获取方法的参数列表
            Parameter[] parameters = method.getParameters();
            String phone = null;
            //获取第一个参数
            if (args.length > 0) {
                UserQuery us = (UserQuery) args[0];
                //获取手机号
                phone = us.getPhone();
            }
            //设置日志对象属性
            lg.setOperateName(operation);
            lg.setPhone(phone);
            // 执行目标方法
            Object result = joinPoint.proceed();
            //结束时间
            long endTime = System.currentTimeMillis();
            //设置操执行时间
            lg.setTime(endTime - startTime);
            lg.setOperateResult(true);
            //保存日志对象
            loginLogMapper.insert(lg);
            return result;
        } catch (Exception e) {
            //设置操作结果
            lg.setOperateResult(false);
            //结束时间
            long endTime = System.currentTimeMillis();
            //设置操执行时间
            lg.setTime(endTime - startTime);
            //设置操作失败原因
            lg.setOperateFailReason(e.getMessage());
            loginLogMapper.insert(lg);
            log.error(e.getMessage());
            throw e;
        }
    }
}
